package muilty_thread.pic_java_design_pattern.SingleThreadedExecution;

import java.util.Random;
import java.util.ResourceBundle;
import java.util.concurrent.Semaphore;

/**
 * @version: 1.0
 * @Description: TODO
 * @author: zZmH
 * @date: 2020/09/09 20:03
 */


public class SemaphoreMain {
    public static void main(String[] args) {

        BoundedResource resource = new BoundedResource(3);
        new UserThread2(resource).start();
        new UserThread2(resource).start();
        new UserThread2(resource).start();
        new UserThread2(resource).start();
        new UserThread2(resource).start();
        new UserThread2(resource).start();
        new UserThread2(resource).start();
    }
}

class Log{
    public static void println(String s) {
        System.out.println(Thread.currentThread().getName() + ": " + s);
    }
}
class BoundedResource{
    private final Semaphore semaphore;
    private final int permits;
    private final static Random random = new Random(314159);

    public BoundedResource( int permits) {
        this.semaphore = new Semaphore(permits);
        this.permits = permits;
    }


    public void use() throws InterruptedException {
        semaphore.acquire();
        try{
            doUse();
        }finally {
            semaphore.release();
        }
    }

    protected void doUse() throws InterruptedException {
        Log.println("BEGIN: used=" + (permits - semaphore.availablePermits()));
        Thread.sleep(random.nextInt(500));
        Log.println("END: used=" + (permits - semaphore.availablePermits()));
    }
}
class UserThread2 extends Thread{
    private static final Random random = new Random(26535);
    private final BoundedResource resource;

    public UserThread2(BoundedResource boundedResource){
        this.resource = boundedResource;
    }


    @Override
    public void run(){
        try{
            while (true) {
                resource.use();
                Thread.sleep(random.nextInt(3000));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();

        }




    }


}